/**
 * 版权所有 Copyright@@2016-03-18 2:18:43
 */
package com.fairy.sso.aspect;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.fairy.sso.annotation.FairyControllerExceptionLog;

/**
 * [FairyControllerAspect.java.java]
 *
 * @Author: [yyk1504@163.com]
 * @CreateDate: [2016-03-18 2:18:43]
 * @Update: [说明本次修改内容] by [yyk1504@163.com] [2016-03-18 2:18:43]
 * @Version: [v1.0]
 */
@Component
@Aspect
public class FairyControllerAspect {
	@Autowired(required=true)
	//private FairyConfig config;
	private Logger log = Logger.getLogger(FairyControllerAspect.class);
	private static String str="";
	private String des="";
	private String cls="";

	@Pointcut("@annotation(com.fairy.sso.annotation.FairyControllerExceptionLog)")    
	public void pointCut() {
	}

	@After("pointCut()")
	public void after(JoinPoint joinPoint) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    
        //HttpSession session = request.getSession();  
		String requestUri = request.getRequestURI();
		String contextPath=request.getContextPath();
		//StringBuffer url=request.getRequestURL();
		requestUri=requestUri.replace(contextPath, "");
		log.info(requestUri+","+"after,"+des+","+cls+", executed end");
	}
	@Before("pointCut()")
	public void before(JoinPoint joinPoint) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    
        //HttpSession session = request.getSession();  
		String requestUri = request.getRequestURI();
		String contextPath=request.getContextPath();
		//StringBuffer url=request.getRequestURL();
		requestUri=requestUri.replace(contextPath, "");
		try {
			des=str+","+getControllerMethodDescription(joinPoint);
			cls="class="+joinPoint.getTarget().getClass().getName()+",method="+ joinPoint.getSignature().getName();
			log.info(requestUri+","+"before,"+des+","+cls);
		} catch (Exception e) {
			e.printStackTrace();
		}

		Object[] args = joinPoint.getArgs();
        if (args != null && args.length > 0 ) {
        	for ( Object obj:args)
        	{
        		log.info(requestUri+","+"before,"+des+","+cls+",param:{"+obj.toString()+"}");
        		/**
        		if(obj instanceof Param)
        		{
        			Param param=(Param)obj;
            		param=setParam(request, session, param);	
            		log.info(requestUri+","+"before,"+des+","+cls+",controller�������:{"+param.toString()+"}");
        		}*/

        	}
        }
	
	}



	@AfterReturning(pointcut = "pointCut()", returning = "returnVal")
	public void afterReturning(JoinPoint joinPoint, Object returnVal) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    
        //HttpSession session = request.getSession();  
		String requestUri = request.getRequestURI();
		String contextPath=request.getContextPath();
		//StringBuffer url=request.getRequestURL();
		requestUri=requestUri.replace(contextPath, "");
		log.info(requestUri+","+"afterReturning,"+des+","+cls+"customer controller afterReturning executed, return result is "+ returnVal);
	}

	@Around("pointCut()")
	public Object around(ProceedingJoinPoint pjp) throws Throwable {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    
        //HttpSession session = request.getSession();  
		String requestUri = request.getRequestURI();
		String contextPath=request.getContextPath();
		//StringBuffer url=request.getRequestURL();
		requestUri=requestUri.replace(contextPath, "");
		Object obj=null; 
		try {
			des=str+","+getControllerMethodDescription(pjp);
			cls="class="+pjp.getTarget().getClass().getName()+",method="+ pjp.getSignature().getName();
			log.info(requestUri+","+"around,"+des+","+cls);    
			obj=pjp.proceed();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return obj;
	}

	@AfterThrowing(pointcut = "pointCut()", throwing = "error")
	public void afterThrowing(JoinPoint jp, Throwable error) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    
        //HttpSession session = request.getSession();  
		String requestUri = request.getRequestURI();
		String contextPath=request.getContextPath();
		//StringBuffer url=request.getRequestURL();
		requestUri=requestUri.replace(contextPath, "");
		try {
			des=str+","+getControllerMethodDescription(jp);
			cls="class="+jp.getTarget().getClass().getName()+",method="+ jp.getSignature().getName();
			log.info(requestUri+","+"afterThrowing,"+des+","+cls+","+error.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
    
    
    /**  
     * ��ȡע���жԷ�����������Ϣ ����Controller��ע��  
     *  
     * @param joinPoint �е�  
     * @return ��������  
     * @throws Exception  
     */    
     @SuppressWarnings("rawtypes")
	public  static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {    
        String targetName = joinPoint.getTarget().getClass().getName();    
        String methodName = joinPoint.getSignature().getName();    
        Object[] arguments = joinPoint.getArgs();    
        Class targetClass = Class.forName(targetName);    
        Method[] methods = targetClass.getMethods();    
        String description = "";    
         for (Method method : methods) {    
             if (method.getName().equals(methodName)) {    
                Class[] clazzs = method.getParameterTypes();    
                 if (clazzs.length == arguments.length) {    
                    description = method.getAnnotation(FairyControllerExceptionLog.class).description();    
                     break;    
                }    
            }    
        }    
         return description;    
    }    
    /**
 	private Param setParam(HttpServletRequest request, HttpSession session,
 			Param param) {

 		String appId =fairyConfig.getAppId();
		String uid=UUIDUtil.getUUID();
		param.setTraceId(uid);//��ѷ�ÿ�ε��õ�Ψһ��ʶ��UUID
	    param.setSessionId(session.getId()) ; //�Ựid
	    param.setAppId(appId); //��ѷ�Ӧ��ϵͳ Id
	    param.setClientIp(NetUtil.getIpAddr(request)); //����ip,���Կͻ�������Ip��ַ
	    param.setConsumerAddress(RpcContext.getContext().getLocalAddressString()); //��ѷ�ip��ַ

	    param.setReferer (request.getHeader("refer"));// �ͻ������ַ
	    param.setCallTime (DateUtil.getFormatCurrentDate("yyyy-MM-dd HH:mm:ss"));//��ѷ�ÿ�ε��õĵ�ʱ��(û����һ�ζ���Ҫ���»�ȡʱ��)
	    //param.setTrainCode ("demo");//��ѷ�һ������ҵ���У����,��ת�ˣ�����,Ϊһ��������
	    
		return param;

 	}
 	*/
}
